package com.testitems.common.web.result;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Data
@Accessors(chain = true)
@Builder
@AllArgsConstructor
public class Result<T> implements Serializable {
	private static final long serialVersionUID = 8004487252556526569L;

	/**
     * 响应码
     */
    private int code;

    /**
     * 是否成功
     */
    private boolean success;

    /**
     * 响应消息
     */
    private String message;

    /**
     * 响应数据
     */
    private T data;

    /**
     * 响应时间
     */
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date time;

    public Result() {
        time  = new Date();
    }

    public Result(ResultCode resultCode, String message) {
        time = new Date();
        this.code = resultCode.getCode();
        this.message = message;
    }

    public static Result<Boolean> result(boolean flag){
        if (flag){
            return ok();
        }
        return fail();
    }

    public static Result<Boolean> result(ResultCode resultCode){
        return result(resultCode,null);
    }

    public static <T> Result<T> result(ResultCode resultCode, T data){
        return result(resultCode,null,data);
    }

    public static <T> Result<T> result(ResultCode resultCode, String message, T data){
        boolean success = false;
        if (resultCode.getCode() == ResultCode.SUCCESS.getCode()){
            success = true;
        }
        String apiMessage = resultCode.getMessage();
        if (StringUtils.isBlank(message)){
            message = apiMessage;
        }
        return (Result<T>) Result.builder()
                .code(resultCode.getCode())
                .message(message)
                .data(data)
                .success(success)
                .time(new Date())
                .build();
    }

    public static Result<Boolean> ok(){
        return ok(null);
    }

    public static <T> Result<T> ok(T data){
        return result(ResultCode.SUCCESS,data);
    }

    public static <T> Result<T> ok(T data, String message){
        return result(ResultCode.SUCCESS,message,data);
    }

    public static Result<Map<String,Object>> okMap(String key, Object value){
        Map<String,Object> map = new HashMap<>(1);
        map.put(key,value);
        return ok(map);
    }

    public static Result<Boolean> fail(ResultCode resultCode){
        return result(resultCode,null);
    }

    public static Result<String> fail(String message){
        return new Result<String>()
                .setCode(ResultCode.FAIL.getCode())
                .setMessage(message)
                .setSuccess(false);
    }

    public static <T> Result<T> fail(ResultCode resultCode, T data){
        if (ResultCode.SUCCESS == resultCode){
            throw new RuntimeException("失败结果状态码不能为" + ResultCode.SUCCESS.getCode());
        }
        return result(resultCode,data);

    }

    public static Result<String> fail(Integer errorCode, String message){
        return new Result<String>()
                .setSuccess(false)
                .setCode(errorCode)
                .setMessage(message);
    }

    public static Result<Map<String,Object>> fail(String key, Object value){
        Map<String,Object> map = new HashMap<>(1);
        map.put(key,value);
        return result(ResultCode.FAIL,map);
    }

    public static Result<Boolean> fail() {
        return fail(ResultCode.FAIL);
    }
}